/*
 * Copyright (C) 2016 Lokiy(liulongke@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  　　　　http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.lokiy.core

import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.activity.result.ActivityResultCaller
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import com.lokiy.core.activity.CommonActivity
import com.lokiy.core.internal.IStore
import java.util.*

/**
 * RequestForResult
 * @author Lokiy
 * 2021-06-09 16:14
 */
interface RequestForResult {

    private val resultCallBacks: Deque<ForResult>
        get() = if (this is IStore) {
            getTag("resultCallBacks") ?: setTagIfAbsent("resultCallBacks", ArrayDeque())
        } else {
            throw IllegalArgumentException("must be implements IStore")
        }
    private val activityForResult
        get() = if (this is IStore) {
            getTag("activityForResult") ?: setTagIfAbsent(
                "activityForResult",
                when (this) {
                    is ActivityResultCaller -> registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                        resultCallBacks.pop()?.let {
                            it(result.resultCode, result.data ?: Intent())
                        }
                    }
                    else -> {
                        throw IllegalArgumentException("must be Fragment or ComponentActivity")
                    }
                }
            )

        } else {
            throw IllegalArgumentException("must be implements IStore")
        }

    /**
     * 感觉不友好 要怎么优化呢。。。
     * 需要在Activity.onCreate 或者 Fragment.onAttach/onCreate中调用该方法
     */
    fun registerRequest() {
        activityForResult
    }

    /**
     * 启动 startForResult
     */
    fun startForResult(cls: Class<*>? = null, intent: Intent.() -> Unit = {}, callback: ForResult) {
        resultCallBacks.push(callback)
        if (cls != null) {
            if (Fragment::class.java.isAssignableFrom(cls)) {
                activityForResult.launch(CommonActivity.getIntent(launchContext(), cls, Intent().apply(intent)))
            } else {
                activityForResult.launch(Intent(launchContext(), cls).apply(intent))
            }
        } else {
            activityForResult.launch(Intent().apply(intent))
        }
    }

    /**
     * 启动的 context
     */
    private fun launchContext(): Context =
        if (this is Activity) this else if (this is Fragment) this.requireActivity() else throw IllegalArgumentException()

}

/**
 * 返回值
 */
typealias ForResult = (resultCode: Int, intent: Intent) -> Unit